package com.cy.pj.common.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 在此切面对象中为目标对象做chche功能增强
 */
@Aspect
@Component
public class SysCacheAspect {

    //基于map对象作为cache，存储从数据库查询到的数据
    private Map<String,Object> cache = new ConcurrentHashMap<>();

//    @Pointcut("bean(*ServiceImpl)")
//    @Pointcut("execution(* com.cy.pj..*.findBrands(..))")//细粒度切入点
    @Pointcut("@annotation(com.cy.pj.common.annotation.RequiredCache)")
    public void doCache(){}

//    @Pointcut("execution(* com.cy.pj..*.deleteById(..))")
    @Pointcut("@annotation(com.cy.pj.common.annotation.ClearCache)")
    public void doClearCache(){}

    @AfterReturning("doClearCache()")
    public void doAfterReturning(){//在目标方法成功结束以后执行此方法
        cache.clear();
    }


    @Around("doCache()")
    public Object doCacheAround(ProceedingJoinPoint joinPoint)throws Throwable{
        //1.从缓存取数据，假如缓存中有则直接返回，没有则查数据库
        Object result=cache.get("cacheKey");//暂时先将key设置为固定值
        if (result!=null)return result;
        //2.查询数据库
        result = joinPoint.proceed();
        //3.将数据储存到缓存对象
        cache.put("cacheKey", result);
        System.out.println("查询");
        return result;//目标方法执行结果
    }

    /**
     * 当前应用程序存在几个问题？
     * 1）key设计（Key后续在项目中一般都是基于请求参数动态生成）
     * 2）切入点的设计（缓存一般应用于查询方法）
     * 3）脏读问题？（数据库中的数据已经被删除，但缓存中还有）
     */

//    @Around("doClearCache()")
//    public Object doClearCache(ProceedingJoinPoint joinPoint) throws Throwable {
//
//        Object obj = joinPoint.proceed();
//        cache.clear();
//        return obj;
//    }



}
